#!/usr/bin/env python
#		Copyright (C) Ricardo Lameiro 2008
#		Bicicleledpov.py v 0.01 - transfer and control of the hardware via Serial port
#       
#       This program uses the pyserial module tha can be used in Windows and 
#       *nixes OSes. You can download this module at 
#       http://pyserial.sourceforge.net/
#
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
""" bledpov.py --

 UI generated by GUI Builder Build 146 on 2008-06-27 02:36:13 from:
    /home/lameiro/python/bledpov/bledpov.ui
 This file is auto-generated.  Only the code within
    '# BEGIN USER CODE (global|class)'
    '# END USER CODE (global|class)'
 and code inside the callback subroutines will be round-tripped.
 The 'main' function is reserved.
"""

from Tkinter import *
from bledpov_ui import Bledpov

# BEGIN USER CODE global
import serial
import os
import tkMessageBox
from sys import platform # import the platform object for system platform checking

def infomsg():
	"""This is the function that calls a Graphic Info message box
	USAGE : infomsg("title", "text")
	"""
	in_msg = tkMessageBox.showinfo("test", "This is a test")
	return in_msg
def errormsg():
	"""This is the function that calls a Graphic error message box
	USAGE : errormsg("title", "text")
	"""
	err_msg = tkMessageBox.showerror("ERROR", "Command unsucsessful. \n Check if hardware is connected or \n check the serial port used.") 
	
	
def scan():
	"""This Function Searches for active serial port on your computer.
	Scan() function uses two diferent methods to find the active serial port.
	One of the methods is for the linux platform (linux kernel 2.x.x +) and the other 
	for the windows 32bits platform. the choises is made using a conditional statement 
	comparing the result of sys.platform object.
	==== This function returns a list ====
	"""
	if sys.platform == "linux2": #Check if the system is Linux Kernel  2.x.x
	
		lista = []    
		lista = os.listdir('/dev/')   #listing the devices present on the /dev folder
    
		serial_ls =[]
    
		for item in lista:  # Searches for item inside the /dev folder 
			a = item[0:3]   #with the first "tty" letters (something like "$ ls /dev/tty* "
			if a == "tty":
				serial_ls.append(item)
		else:
			pass
    
		available = []
    
		for item in serial_ls: #search active ports and append the result to a list
			try:
				s = serial.Serial("/dev/"+item)
				available.append(s.portstr)
				s.close()   
			except serial.SerialException:
				pass
		return available
	
	elif sys.platform == "win32": #Check if system platform is Windows 32 bits
		available = []	#Search active ports and append the result to a list
		for i in range(1024):
			try:
				s = serial.Serial(i)
				available.append( (i, s.portstr))
				s.close()   #explicit close 'cause of delayed GC in java
			except serial.SerialException:
				pass
		return available
		
	else:    # Shows a graphic error message box 
		errormsg("Platform Error", "This software can only be runed in: \n Linx 2.xx and Windows 32 bits")



ports = scan()



cmd1 = "\x01" #Firmware API Commands assignement
cmd2 = "\x02" # |
cmd3 = "\x03" # |
cmd4 = "\x04" # |



# END USER CODE global

class CustomBledpov(Bledpov):
    pass

    # BEGIN CALLBACK CODE
    # ONLY EDIT CODE INSIDE THE def FUNCTIONS.

    # _spinbox_1_command --
    #
    # Callback to handle _spinbox_1 widget option -command
    def _spinbox_1_command(self, *args):
        pass

    # _spinbox_1_invalidcommand --
    #
    # Callback to handle _spinbox_1 widget option -invalidcommand
    def _spinbox_1_invalidcommand(self, *args):
        pass

    # _spinbox_1_validatecommand --
    #
    # Callback to handle _spinbox_1 widget option -validatecommand
    def _spinbox_1_validatecommand(self, *args):
        pass

    # _spinbox_1_xscrollcommand --
    #
    # Callback to handle _spinbox_1 widget option -xscrollcommand
    def _spinbox_1_xscrollcommand(self, *args):
        pass

    # b_scan_command --
    #
    # Callback to handle b_scan widget option -command
    def b_scan_command(self, *args):
    	
        self.serial_listbox.delete(0, END) # this delete all items on the listbox (refresh)
        
        # A loop that inserts the diferent serial port avaiable into the serial_listbox
        
        for item in scan():
    		self.serial_listbox.insert(END, item)
    		
    	

    # send_cmd1_command --
    #
    # Callback to handle send_cmd1 widget option -command
    
    
    def send_cmd1_command(self, *args):   # command 1 button AKA Dummy command
    	serial_selected = self.serial_listbox.curselection()     # Select the serial port that is 
        selected_port = self.serial_listbox.get(serial_selected) # Highlighted in the list box
        
    	ser = serial.Serial(selected_port, timeout = 5)  # configure the serial port
    	ser.open         # opens the serial port
    	ser.write(cmd1)  # Send the command 1 to the serial port
    	rcv = ser.read() # Reads the response (if any) and saves it in rcv var
    	ser.close        # close the serial port  
    	
    	if rcv == cmd1:  # check if the command was sucessful (refer to the firmaware api)
		infomsg("Command sucessful", "Command sucessful") # sucessful command message
	else:
		errormsg()                                        # error message     
		

    # send_cmd2_command --
    #
    # Callback to handle send_cmd2 widget option -command
    
    
    def send_cmd2_command(self, *args): #command 2 AKA Firmware version command (not debuged yet)
    	serial_selected = self.serial_listbox.curselection()     # Select the serial port that is 
        selected_port = self.serial_listbox.get(serial_selected) # highlighted in the listbox
        
    	ser = serial.Serial(selected_port, timeout = 5) # configure the serial port
    	ser.open          # open te serial port
    	ser.write(cmd2)   # send the command 2 to the serial port  
    	rcv = ser.read(3) # read 3 bytes from serial port (refer to the firmware api)
    	ser.close         # close the serial port
    	
    	if len(rcv) == 3:
		infomsg("Command sucessful", "FIRMWARE VERSION:" + rcv)
	else:
		errormsg()
		

    # send_cmd3_command --
    #
    # Callback to handle send_cmd3 widget option -command
    
    
    def send_cmd3_command(self, *args):
        pass

    # send_cmd4_command --
    #
    # Callback to handle send_cmd4 widget option -command
    def send_cmd4_command(self, *args):
        pass

    # serial_listbox_xscrollcommand --
    #
    # Callback to handle serial_listbox widget option -xscrollcommand
    def serial_listbox_xscrollcommand(self, *args):
        pass

    # _button_1_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def _button_1_command(self, *args):
        pass

    # _button_2_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def _button_2_command(self, *args):
        pass

    # _listbox_2_xscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def _listbox_2_xscrollcommand(self, *args):
        pass

    # _listbox_2_yscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def _listbox_2_yscrollcommand(self, *args):
        pass

    # _scrollbar_1_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def _scrollbar_1_command(self, *args):
        pass

    # _scrollbar_2_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def _scrollbar_2_command(self, *args):
        pass

    # b_send_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def b_send_command(self, *args):
        serial_selected = self.serial_listbox.curselection()
        selected_port = self.serial_listbox.get(serial_selected)

    # cmd_listbox_xscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def cmd_listbox_xscrollcommand(self, *args):
        pass

    # cmd_listbox_yscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def cmd_listbox_yscrollcommand(self, *args):
        pass

    # cmd_scrollbar_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def cmd_scrollbar_command(self, *args):
        pass

    # serial_listbox_yscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def serial_listbox_yscrollcommand(self, *args):
        pass

    # serial_scrollbar_command --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def serial_scrollbar_command(self, *args):
		pass

    # seriallistbox_xscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def seriallistbox_xscrollcommand(self, *args):
        pass

    # seriallistbox_yscrollcommand --
    #
    # Legacy command found in callback code. Add user comments inside body.
    def seriallistbox_yscrollcommand(self, *args):
        pass

    # END CALLBACK CODE

    # BEGIN USER CODE class
	def serial_port(self, *args):
		serial_selected = self.serial_listbox.curselection()
        selected_port = self.serial_listbox.get(serial_selected)
        return selected_port
    # END USER CODE class

def main():
    # Standalone Code Initialization
    # DO NOT EDIT
    try: userinit()
    except NameError: pass
    root = Tk()
    demo = CustomBledpov(root)
    root.title('bledpov')
    try: run()
    except NameError: pass
    root.protocol('WM_DELETE_WINDOW', root.quit)
    root.mainloop()

if __name__ == '__main__': main()
